/*
 * 文件名： HttpsTransport.java
 * 
 * 工程名称: bis-bank-pab
 *
 * Gopay
 *
 * 创建日期： 2017年8月14日
 *
 * Copyright(C) 2017, by www.gopay.com.cn Inc.All rights reserved.
 *
 * 原始作者: 宣广海
 *
 */
package com.gopay.bis.pab.apay.operation;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLDecoder;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Iterator;
import java.util.Map;
import java.util.TreeMap;
import java.util.zip.GZIPInputStream;
import java.util.zip.ZipException;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 
 *
 * @author 宣广海
 *
 * @version
 *
 * @since 2017年8月14日
 */
public class Transport {

	private static Logger logger = LoggerFactory.getLogger(Transport.class);

	private static class MyTrustManager implements X509TrustManager {
		public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
		}

		public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
		}

		public X509Certificate[] getAcceptedIssuers() {
			return new X509Certificate[] {};
		}
	}

	private static class MyHostnameVerifier implements HostnameVerifier {
		public boolean verify(String hostname, SSLSession session) {
			return true;
		}
	}

	public static String handlePost(TreeMap<String, String> postmap, String openUrl, String interfaceName) {
		String url = openUrl + interfaceName;
		logger.info("请求URL及接口为：" + url);
		if (url.contains("https")) {
			return httpsMethodPost(url, postmap, "UTF-8");
		} else {
			return httpMethodPost(url, postmap, "UTF-8");
		}
	}

	public static String handleMerchantPost(TreeMap<String, String> postmap, TreeMap<String, String> getmap,
			String openUrl, String interfaceName) {
		String url = openUrl + interfaceName + "?open_id=" + getmap.get("open_id") + "&lang=" + getmap.get("lang")
				+ "&timestamp=" + getmap.get("timestamp") + "&randStr=" + getmap.get("randStr");
		;
		logger.info("请求URL及接口为：" + url);
		if (url.contains("https")) {
			return httpsMethodPost(url, postmap, "UTF-8");
		} else {
			return httpMethodPost(url, postmap, "UTF-8");
		}
	}

	public static String handleGetFilePost(TreeMap<String, String> postmap, TreeMap<String, String> getmap,
			String openUrl, String interfaceName, String callType) {
		String url = openUrl + interfaceName + "?open_id=" + getmap.get("open_id") + "&lang=" + getmap.get("lang")
				+ "&timestamp=" + getmap.get("timestamp") + "&randStr=" + getmap.get("randStr");
		;
		logger.info("请求URL及接口为：" + url);
		if ("gzip".equals(callType)) {
			if (url.contains("https")) {
				return httpsMethodPostGZIP(url, postmap, "UTF-8");
			} else {
				return httpMethodPostGZIP(url, postmap, "UTF-8");
			}
		} else {
			if (url.contains("https")) {
				return httpsMethodPost(url, postmap, "UTF-8");
			} else {
				return httpMethodPost(url, postmap, "UTF-8");
			}
		}

	}

	public static String httpsMethodPost(String url, TreeMap<String, String> paramsMap, String gb) {
		if (null == gb || "".equals(gb)) {
			gb = "UTF-8";
		}
		String params = null;
		if (null != paramsMap) {
			params = getParamStr(paramsMap);
		}
		StringBuffer sb = new StringBuffer();
		URL urls;
		HttpsURLConnection uc = null;
		BufferedReader in = null;
		try {
			SSLContext sc = SSLContext.getInstance("SSL");
			sc.init(null, new TrustManager[] { new MyTrustManager() }, new java.security.SecureRandom());
			urls = new URL(url);
			uc = (HttpsURLConnection) urls.openConnection();
			uc.setSSLSocketFactory(sc.getSocketFactory());
			uc.setHostnameVerifier(new MyHostnameVerifier());
			uc.setRequestMethod("POST");
			uc.setDoOutput(true);
			uc.setDoInput(true);
			uc.setUseCaches(false);
			uc.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
			uc.connect();
			DataOutputStream out = new DataOutputStream(uc.getOutputStream());
			out.write(params.getBytes(gb));
			out.flush();
			out.close();
			in = new BufferedReader(new InputStreamReader(uc.getInputStream(), gb));
			String readLine = "";
			while ((readLine = in.readLine()) != null) {
				sb.append(readLine);
			}
			if (in != null) {
				in.close();
			}
			if (uc != null) {
				uc.disconnect();
			}
		} catch (Exception e) {
			logger.info("err message==" + e);
		} finally {
			if (uc != null) {
				uc.disconnect();
			}
		}
		return URLDecoder.decode(sb.toString());
	}

	public static String httpMethodPost(String url, TreeMap<String, String> paramsMap, String gb) {
		if (null == gb || "".equals(gb)) {
			gb = "UTF-8";
		}
		String params = null;
		if (null != paramsMap) {
			params = getParamStr(paramsMap);
		}
		logger.error("params====" + params);
		StringBuffer sb = new StringBuffer();
		URL urls;
		HttpURLConnection uc = null;
		BufferedReader in = null;
		try {
			urls = new URL(url);
			uc = (HttpURLConnection) urls.openConnection();
			uc.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
			uc.setDoOutput(true);
			uc.setDoInput(true);
			uc.setRequestMethod("POST");
			uc.setUseCaches(false);
			uc.connect();
			DataOutputStream out = new DataOutputStream(uc.getOutputStream());
			out.write(params.getBytes(gb));
			out.flush();
			out.close();
			in = new BufferedReader(new InputStreamReader(uc.getInputStream(), gb));
			String readLine = "";
			while ((readLine = in.readLine()) != null) {
				sb.append(readLine);
			}
			if (in != null) {
				in.close();
			}
			if (uc != null) {
				uc.disconnect();
			}
		} catch (IOException e) {
			logger.info("err message==" + e);
		} finally {
			if (uc != null) {
				uc.disconnect();
			}
		}
		return sb.toString();
	}

	public static String httpMethodPostGZIP(String url, TreeMap<String, String> paramsMap, String gb) {
		System.out.println("===url：" + url);
		if (null == gb || "".equals(gb)) {
			gb = "UTF-8";
		}
		String params = null;
		if (null != paramsMap) {
			params = getParamStr(paramsMap);
		}
		logger.error("params====" + params);
		StringBuffer sb = new StringBuffer();
		URL urls;
		HttpURLConnection uc = null;
		BufferedReader in = null;
		try {
			urls = new URL(url);
			uc = (HttpURLConnection) urls.openConnection();
			uc.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
			uc.setDoOutput(true);
			uc.setDoInput(true);
			uc.setRequestMethod("POST");
			uc.setUseCaches(false);
			uc.connect();
			DataOutputStream out = new DataOutputStream(uc.getOutputStream());
			out.write(params.getBytes(gb));
			out.flush();
			out.close();
			in = new BufferedReader(new InputStreamReader(new GZIPInputStream(uc.getInputStream()), gb));

			String readLine = "";
			while ((readLine = in.readLine()) != null) {
				sb.append(readLine).append("\n");
			}
			if (in != null) {
				in.close();
			}
			if (uc != null) {
				uc.disconnect();
			}
		} catch (ZipException e) {
			logger.info("err message==" + e);
		} catch (IOException e) {
			logger.error(e.getMessage(), e);
		} finally {
			if (uc != null) {
				uc.disconnect();
			}
		}
		return sb.toString();
	}

	public static String httpsMethodPostGZIP(String url, TreeMap<String, String> paramsMap, String gb) {
		System.out.println("===url：" + url);
		if (null == gb || "".equals(gb)) {
			gb = "UTF-8";
		}
		String params = null;
		if (null != paramsMap) {
			params = getParamStr(paramsMap);
		}
		logger.error("params====" + params);
		StringBuffer sb = new StringBuffer();
		URL urls;
		HttpsURLConnection uc = null;
		BufferedReader in = null;
		try {
			SSLContext sc = SSLContext.getInstance("SSL");
			sc.init(null, new TrustManager[] { new MyTrustManager() }, new java.security.SecureRandom());
			urls = new URL(url);
			uc = (HttpsURLConnection) urls.openConnection();
			uc.setSSLSocketFactory(sc.getSocketFactory());
			uc.setHostnameVerifier(new MyHostnameVerifier());
			uc.setRequestMethod("POST");
			uc.setDoOutput(true);
			uc.setDoInput(true);
			uc.setUseCaches(false);
			uc.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
			uc.connect();
			DataOutputStream out = new DataOutputStream(uc.getOutputStream());
			out.write(params.getBytes(gb));
			out.flush();
			out.close();
			in = new BufferedReader(new InputStreamReader(new GZIPInputStream(uc.getInputStream()), gb));
			String readLine = "";
			while ((readLine = in.readLine()) != null) {
				sb.append(readLine).append("\n");
			}
			if (in != null) {
				in.close();
			}
			if (uc != null) {
				uc.disconnect();
			}
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
		} finally {
			if (uc != null) {
				uc.disconnect();
			}
		}
		return sb.toString();
	}

	private static String getParamStr(TreeMap<String, String> paramsMap) {
		StringBuilder param = new StringBuilder();
		for (Iterator<Map.Entry<String, String>> it = paramsMap.entrySet().iterator(); it.hasNext();) {
			Map.Entry<String, String> e = it.next();
			param.append("&").append(e.getKey()).append("=").append(e.getValue());
		}
		return param.toString().substring(1);
	}
}
